/*
 * Breif: 编织文件之前自动增加的数据
 *
 * ChangeLog
 * Date             Author          Notes
 * 2014.09.23       Herbert         First version
 * 2014.11.03       Herbert         修改pk_need_loop中范围相等的情况，返回－１
 * 2014.12.20       Herbert         增加前缀编织数据的发送
 */

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mh/common.h>
#include <mh/sram.h>
#include "knit.h"
#include "backpiece.h"
#include "prefixknit.h"


/*
 * @param pk_cnt CNT前缀数据
 * @param loop_start 节约开始行
 * @param loop_end 节约结束行
 * @param loop_times 节约次数
 */
void pk_setup_loop_data_cnt(MH_KNIT *p,
                            uchar *cnt_buf,
                            short loop_start,
                            short loop_end,
                            short loop_times)
{
    uchar *pbuf = cnt_buf;
    int hd_start;
    int hd_end;
    int row;
    hd_start = p->hangding_start;
    hd_end = hd_start + 1;
    /* 第1行 */
    /* 前缀编织数据的第一行，采用花样第一行速度，其他使用行定速度 */
    row = (loop_times == 0) ? 1 : hd_start;
    KNIT_PAGE *pcon = GetControlPage(p, row);
    if(pcon)
    {
        memcpy ((void*)pbuf, (void*)pcon, sizeof(KNIT_PAGE));
    }

    if (pcon->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 1);
    }
    if (pcon->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 1);
    }
    if (pcon->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 2);
    }
    if (pcon->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 2);
    }
    /* 第2行 */
    pbuf = cnt_buf + sizeof(KNIT_PAGE);
    row = (loop_times == 0) ? 2 : hd_end;
    pcon = GetControlPage(p, row);
    memcpy ((void*)pbuf, (void*)pcon, sizeof(KNIT_PAGE));

    if (pcon->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 1);
    }
    if (pcon->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 1);
    }
    if (pcon->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 2);
    }
    if (pcon->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 2);
    }
    if (loop_times == 0)
    {
        SET_LOOP_START(pbuf, 0);
        SET_LOOP_END(pbuf, 0);
        SET_LOOP_NUM(pbuf, 0);
    }
    else
    {
        SET_LOOP_START(pbuf, loop_start);
        SET_LOOP_END(pbuf, loop_end);
        SET_LOOP_NUM(pbuf, loop_times);
    }
}
/*
 * 判断是否需要行定
 * @ret: 0:指定行的范围大于当前编织范围
 *       1:片子往左偏移，落右边
 *       2:片子往右偏移,落左边
 *       3:不需要落布
 */
int pk_need_loop(MH_KNIT *p, int row)
{
    PAT_RANGE range = { 0 };
    /* 前片结束行范围 */
    PAT_RANGE fp_er = { 0 };
    /* 后片结束行范围 */
    PAT_RANGE bp_er = { 0 };
    int l = 0;
    int r = 0;

    /* 前片结束行 */
    int fp_end_row = backpiece_get_fp_end_row(p);
    /* 后片结束行 */
    int bp_end_row = backpiece_get_end_row(p);

    int sp = p->start_needle;
    sp -= p->left_bound;

    backpiece_get_pattern_range(p, row, &range);
    backpiece_get_pattern_range(p, fp_end_row, &fp_er);
    backpiece_get_pattern_range(p, bp_end_row, &bp_er);

    /* 超过最后一行宽度的部分为废纱，如果落掉的是废纱，不需要打行定 */
    if (p->need_loop & LOOP_FRY_BIT)
    {
        /* 前片 */
        if ((range.pat_start + sp <= p->fper_pat_start + p->sp) &&
            (range.pat_end + sp >= p->fper_pat_end + p->sp))
        {
            /* 打三次行定 */
            p->need_loop |= LOOP_YC_BIT;
        }
    }

    if (p->need_loop & LOOP_BRY_BIT)
    {
        /* 后片 */
        if ((range.pat_start + sp <= p->bper_pat_start + p->sp) &&
            (range.pat_end + sp >= p->bper_pat_end + p->sp))
        {
            /* 打三次行定 */
            p->need_loop |= LOOP_YC_BIT;
        }
    }

    printf("pos: %d-%d, %d-%d\n", range.pat_start + sp, p->knit_start + p->sp, range.pat_end + sp, p->knit_end + p->sp);
    /* 不需要落布 */
    if ((range.pat_start + sp <= p->knit_start + p->sp) &&
        (range.pat_end + sp >= p->knit_end + p->sp))
    {
        /* 指定行的范围大于当前编织范围 */
        return 0;
    }

    /* 落左边 */
    if (p->knit_start + p->sp < range.pat_start + sp)
    {
        l =  2;
    }

    /* 落右边 */
    if (p->knit_end + p->sp > range.pat_end + sp)
    {
        r = 1;
    }

    return l + r;
}
/*
 * 获取行定类型１数据，先行定，再落右边
 * @param row 从第row行开始编织,从１开始
 * @param[out] pcnt 控制缓冲区
 * @param[out] ppat 花样缓冲区
 */
int pk_get_loop_data1(MH_KNIT *p, int row)
{
    int i = 0;
    int hd_start = 0;
    int hd_end = 0;
    uchar *pbuf;
    PAT_RANGE range = { 0 };
    int max_start;
    int d;
    int loop_num;
    int first_loop_times = 3;

    PK_DATA *pcnt;
    PK_DATA *ppat;

    int total_needle = p->total_needle;

    /* 行定起点 */
    int start = 0;
    /* 行定终点 */
    int end = 0;

    p->pk_data.pcnt.rows = 0;
    FREE(p->pk_data.pcnt.buf);

    p->pk_data.ppat.rows = 0;
    FREE(p->pk_data.ppat.buf);

    hd_start = p->hangding_start;
    hd_end = hd_start + 1;

    if ((p->knit_page == NULL) || (p->total_line < hd_end))
    {
        return 1;
    }

    int sp = p->start_needle;
    sp -= p->left_bound;

    printf("sp = %d\n", sp);

    backpiece_get_pattern_range(p, row, &range);

    start = __min(range.pat_start + sp - 1, p->knit_start + p->sp - 1);
    end = __max(range.pat_end + sp - 1, p->knit_end + p->sp - 1);
    max_start = __max(range.pat_start + sp - 1, p->knit_start + p->sp - 1);

    if ((start < 0) || (end < 0) ||
        (start > total_needle) || (end > total_needle))
    {
        return 0;
    }

    printf ("start = %d, end = %d\n", start, end);
    /*
     * 1----> 编织
     * 2<---- 编织    1,2慢速
     * 3----> 编织
     * 4<---- 编织    3,4循环10次
     * 5----> 落布
     * 6<---- 落布    5,6循环2次
     * 7----> 编织
     * 8<---- 编织    7,8循环15次
     */

    p->pk_data.pat_width = total_needle;

    ppat = &p->pk_data.ppat;

    /* pat */
    ppat->rows = 6;
    ppat->buf = (uchar*)calloc(total_needle * ppat->rows, sizeof (uchar));
    /* 行定 */
    for (i = start; i <= end; i++)
    {
        ppat->buf[0 * total_needle + i] = (i % 2) ? 4 : 5;
        ppat->buf[1 * total_needle + i] = (i % 2) ? 4 : 5;
    }
    /* 落布 */
    for (i = range.pat_end + sp; i <= end; i++)
    {
        ppat->buf[2 * total_needle + i] = 4;
        ppat->buf[3 * total_needle + i] = 4;
    }
    /* 行定 */
    for (i = start; i <= range.pat_end + sp - 1; i++)
    {
        ppat->buf[4 * total_needle + i] = (i % 2) ? 4 : 5;
        ppat->buf[5 * total_needle + i] = (i % 2) ? 4 : 5;
    }

    /* cnt */
    pcnt = &p->pk_data.pcnt;

    if ((p->need_loop & LOOP_SY_BIT) ||
        ((p->need_loop & LOOP_KC_BIT) == KNITING))
    {
        first_loop_times = 25;
    }
    else if (p->need_loop & LOOP_NL_BIT)
    {
        first_loop_times = 10;
    }

    pcnt->rows = (first_loop_times > 10) ? 6 : 8;
    pcnt->buf = (uchar*)calloc(pcnt->rows, sizeof(KNIT_PAGE));

    //printf("cnt_rows: %d, %d\n", pcnt->rows, first_loop_times);

    /* 1, 2行 */
    pk_setup_loop_data_cnt(p, pcnt->buf, 1, 2, 0);
    /* 3, 4行定 */
    pk_setup_loop_data_cnt(p, pcnt->buf + 2 * sizeof(KNIT_PAGE), 3, 4, first_loop_times - 1);

    KNIT_PAGE *pcon_hd_start = GetControlPage(p, hd_start);
    /* 第5，6行，落布 */
    pbuf = pcnt->buf + 4 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)pcon_hd_start, sizeof(KNIT_PAGE));
    SET_SYS1_FPR(pbuf, 3);
    SET_SYS1_FC(pbuf, 8);
    SET_SYS1_BPR(pbuf, 3);
    SET_SYS1_BC(pbuf, 8);
    SET_SYS1_FAC(pbuf, 0x01 << 4);
    SET_SYS1_BAC(pbuf, 0x01 << 4);
    SET_SYS1_YC(pbuf, 0);

    SET_SYS2_FPR(pbuf, 4);
    SET_SYS2_FC(pbuf, 8);
    SET_SYS2_BPR(pbuf, 4);
    SET_SYS2_BC(pbuf, 8);
    SET_SYS2_FAC(pbuf, 0x01 << 4);
    SET_SYS2_BAC(pbuf, 0x01 << 4);
    SET_SYS2_YC(pbuf, 0);

    pbuf = pcnt->buf + 5 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 4 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    SET_LOOP_START(pbuf, 5);
    SET_LOOP_END(pbuf, 6);
    SET_LOOP_NUM(pbuf, 2);

    /* 7,8行定 */
    if (pcnt->rows > 6)
    {
        pbuf = pcnt->buf + 6 * sizeof(KNIT_PAGE);
        memcpy((void*)pbuf, (void*)(pcnt->buf + 2 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
        if (pcon_hd_start->flw_1F != 0)
        {
            SET_SYS1_FPR(pbuf, 5);
        }
        if (pcon_hd_start->flw_1B != 0)
        {
            SET_SYS1_BPR(pbuf, 5);
        }
        if (pcon_hd_start->flw_2F != 0)
        {
            SET_SYS2_FPR(pbuf, 6);
        }
        if (pcon_hd_start->flw_2B != 0)
        {
            SET_SYS2_BPR(pbuf, 6);
        }
        pbuf = pcnt->buf + 7 * sizeof(KNIT_PAGE);
        memcpy((void*)pbuf, (void*)(pcnt->buf + 3 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
        if (pcon_hd_start->flw_1F != 0)
        {
            SET_SYS1_FPR(pbuf, 5);
        }
        if (pcon_hd_start->flw_1B != 0)
        {
            SET_SYS1_BPR(pbuf, 5);
        }
        if (pcon_hd_start->flw_2F != 0)
        {
            SET_SYS2_FPR(pbuf, 6);
        }
        if (pcon_hd_start->flw_2B != 0)
        {
            SET_SYS2_BPR(pbuf, 6);
        }

        d = max_start - start;

        if (d <= 10)
        {
            loop_num = 3;
        }
        else if (d <= 15)
        {
            loop_num = 8;
        }
        else
        {
            loop_num = 15;
        }

        if (p->need_loop & LOOP_SY_BIT)
        {
            loop_num = 15;
        }
        //printf("loop_num: %d\n", loop_num);

        SET_LOOP_START(pbuf, pcnt->rows - 1);
        SET_LOOP_END(pbuf, pcnt->rows);
        SET_LOOP_NUM(pbuf, loop_num);
    }
    return 0;
}
/*
 * 获取行定类型１数据，先落右边，再行定
 * @param row 从第row行开始编织,从１开始
 * @param[out] pcnt 控制缓冲区
 * @param[out] ppat 花样缓冲区
 * NOTE:直接落布
 */
int pk_get_loop_data1_noloop(MH_KNIT *p, int row)
{
    int i = 0;
    int hd_start = 0;
    int hd_end = 0;
    uchar *pbuf;
    PAT_RANGE range = { 0 };
    int max_start;
    int d;
    int loop_num;

    PK_DATA *pcnt;
    PK_DATA *ppat;

    int total_needle = p->total_needle;

    /* 行定起点 */
    int start = 0;
    /* 行定终点 */
    int end = 0;

    p->pk_data.pcnt.rows = 0;
    FREE(p->pk_data.pcnt.buf);

    p->pk_data.ppat.rows = 0;
    FREE(p->pk_data.ppat.buf);

    hd_start = p->hangding_start;
    hd_end = hd_start + 1;

    if((p->knit_page == NULL) || (p->total_line < hd_end))
    {
        return 1;
    }

    int sp = p->start_needle;
    sp -= p->left_bound;

    backpiece_get_pattern_range(p, row, &range);

    start = __min(range.pat_start + sp - 1, p->knit_start + p->sp - 1);
    end = __max(range.pat_end + sp - 1, p->knit_end + p->sp - 1);

    if ((start < 0) || (end < 0) ||
        (start > total_needle) || (end > total_needle))
    {
        return 0;
    }

    max_start = __max(range.pat_start + sp - 1, p->knit_start + p->sp - 1);
    printf ("start = %d, end = %d, max_start = %d\n", start, end, max_start);
    /*
     * 1----> 落布
     * 2<---- 落布
     * 3----> 落布
     * 4<---- 落布
     * 5----> 编织慢速
     * 6<---- 编织慢速
     * 7----> 编织快速
     * 8<---- 编织快速    7,8循环15次
     */
    p->pk_data.pat_width = total_needle;

    ppat = &p->pk_data.ppat;

    /* pat */
    ppat->rows = 4;
    ppat->buf = (uchar*)calloc(total_needle * ppat->rows, sizeof (uchar));

    /* 落布 */
    for (i = range.pat_end + sp; i <= end; i++)
    {
        ppat->buf[0 * total_needle + i] = 4;
        ppat->buf[1 * total_needle + i] = 4;
    }
    /* 行定 */
    for (i = start; i <= range.pat_end + sp - 1; i++)
    {
        ppat->buf[2 * total_needle + i] = (i % 2) ? 4 : 5;
        ppat->buf[3 * total_needle + i] = (i % 2) ? 4 : 5;
    }

    /* cnt */
    pcnt = &p->pk_data.pcnt;

    pcnt->rows = 8;
    pcnt->buf = (uchar*)calloc(pcnt->rows, sizeof(KNIT_PAGE));

    /* 第1，2行,落布 */
    pbuf = pcnt->buf;
    memcpy((void*)pbuf, (void*)GetControlPage(p, 1), sizeof(KNIT_PAGE));
    SET_SYS1_FPR(pbuf, 1);
    SET_SYS1_FC(pbuf, 8);
    SET_SYS1_BPR(pbuf, 1);
    SET_SYS1_BC(pbuf, 8);
    SET_SYS1_FAC(pbuf, 0x01 << 4);
    SET_SYS1_BAC(pbuf, 0x01 << 4);
    SET_SYS1_YC(pbuf, 0);

    SET_SYS2_FPR(pbuf, 2);
    SET_SYS2_FC(pbuf, 8);
    SET_SYS2_BPR(pbuf, 2);
    SET_SYS2_BC(pbuf, 8);
    SET_SYS2_FAC(pbuf, 0x01 << 4);
    SET_SYS2_BAC(pbuf, 0x01 << 4);
    SET_SYS2_YC(pbuf, 0);

    pbuf = pcnt->buf + 1 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)pcnt->buf, sizeof(KNIT_PAGE));

    KNIT_PAGE *pcon_hd_start = GetControlPage(p, hd_start);
    /* 3,4行落布 */
    pbuf = pcnt->buf + 2 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)pcon_hd_start, sizeof(KNIT_PAGE));
    SET_SYS1_FPR(pbuf, 1);
    SET_SYS1_FC(pbuf, 8);
    SET_SYS1_BPR(pbuf, 1);
    SET_SYS1_BC(pbuf, 8);
    SET_SYS1_FAC(pbuf, 0x01 << 4);
    SET_SYS1_BAC(pbuf, 0x01 << 4);
    SET_SYS1_YC(pbuf, 0);

    SET_SYS2_FPR(pbuf, 2);
    SET_SYS2_FC(pbuf, 8);
    SET_SYS2_BPR(pbuf, 2);
    SET_SYS2_BC(pbuf, 8);
    SET_SYS2_FAC(pbuf, 0x01 << 4);
    SET_SYS2_BAC(pbuf, 0x01 << 4);
    SET_SYS2_YC(pbuf, 0);

    pbuf = pcnt->buf + 3 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 2 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 5 行,行定 */
    pbuf = pcnt->buf + 4 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)GetControlPage(p, 1), sizeof(KNIT_PAGE));
    if (pcon_hd_start->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 3);
    }
    if (pcon_hd_start->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 3);
    }
    if (pcon_hd_start->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 4);
    }
    if (pcon_hd_start->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 4);
    }

    KNIT_PAGE *pcon_hd_end = GetControlPage(p, hd_end);
    /* 第6行，行定 */
    pbuf = pcnt->buf + 5 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)GetControlPage(p, 2), sizeof(KNIT_PAGE));
    if (pcon_hd_end->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 3);
    }
    if (pcon_hd_end->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 3);
    }
    if (pcon_hd_end->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 4);
    }
    if (pcon_hd_end->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 4);
    }

    SET_LOOP_START(pbuf, 0);
    SET_LOOP_END(pbuf, 0);
    SET_LOOP_NUM(pbuf, 0);

    /* 7 行,行定 */
    pbuf = pcnt->buf + 6 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)pcon_hd_start, sizeof(KNIT_PAGE));
    if (pcon_hd_start->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 3);
    }
    if (pcon_hd_start->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 3);
    }
    if (pcon_hd_start->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 4);
    }
    if (pcon_hd_start->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 4);
    }

    /* 第8行，行定 */
    pbuf = pcnt->buf + 7 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)pcon_hd_end, sizeof(KNIT_PAGE));
    if (pcon_hd_end->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 3);
    }
    if (pcon_hd_end->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 3);
    }
    if (pcon_hd_end->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 4);
    }
    if (pcon_hd_end->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 4);
    }

    d = max_start - start;

    if (d <= 5)
    {
        loop_num = 3;
    }
    else if (d <= 10)
    {
        loop_num = 10;
    }
    else if (d <= 15)
    {
        loop_num = 18;
    }
    else
    {
        loop_num = 25;
    }

    if (p->need_loop & LOOP_SY_BIT)
    {
        loop_num = 25;
    }

    SET_LOOP_START(pbuf, pcnt->rows - 1);
    SET_LOOP_END(pbuf, pcnt->rows);
    SET_LOOP_NUM(pbuf, loop_num);

    return 0;
}
/*
 * 获取行定类型2数据，先行定，再落左边
 * @param row 从第row行开始编织,从１开始
 * @param[out] pcnt 控制缓冲区
 * @param[out] ppat 花样缓冲区
 */
int pk_get_loop_data2(MH_KNIT *p, int row)
{
    int i = 0;
    int hd_start = 0;
    int hd_end = 0;
    uchar *pbuf;
    PAT_RANGE range = { 0 };
    int total_needle = p->total_needle;

    int min_end;
    int d;
    int loop_num;
    int first_loop_times = 2;

    /* 行定起点 */
    int start = 0;
    /* 行定终点 */
    int end = 0;

    PK_DATA *pcnt;
    PK_DATA *ppat;

    p->pk_data.pcnt.rows = 0;
    FREE(p->pk_data.pcnt.buf);

    p->pk_data.ppat.rows = 0;
    FREE(p->pk_data.ppat.buf);

    hd_start = p->hangding_start;
    hd_end = hd_start + 1;

    if ((p->knit_page == NULL) || (p->total_line < hd_end))
    {
        return 1;
    }

    int sp = p->start_needle;
    sp -= p->left_bound;

    backpiece_get_pattern_range(p, row, &range);

    start = __min(range.pat_start + sp - 1, p->knit_start + p->sp - 1);
    end = __max(range.pat_end + sp - 1, p->knit_end + p->sp - 1);
    min_end = __min(range.pat_end + sp - 1, p->knit_end + p->sp - 1);

    if ((start < 0) || (end < 0) ||
        (start > total_needle) || (end > total_needle))
    {
        return 0;
    }
    printf ("type2: start = %d, end = %d\n", start, end);
    /*
     * 1----> 编织
     * 2<---- 编织    1,2慢速
     * 3----> 编织
     * 4<---- 编织    3,4循环10次
     * 5----> 编织　　 纱嘴停到右边
     * 6<---- 落布
     * 7----> 落布
     * 8<---- 落布
     * 9----> 落布
     * 10<---- 编织
     * 11----> 编织
     * 12<--- 编织    11,12循环15次
     */

    /* pat */
    p->pk_data.pat_width = total_needle;

    if ((p->need_loop & LOOP_SY_BIT) ||
        ((p->need_loop & LOOP_KC_BIT) == KNITING))
    {
        first_loop_times = 24;
    }
    else if (p->need_loop & LOOP_NL_BIT)
    {
        first_loop_times = 9;
    }

    ppat = &p->pk_data.ppat;

    ppat->rows = 6;
    ppat->buf = (uchar*)calloc(total_needle * ppat->rows, sizeof (uchar));
    /* 行定 */
    for (i = start; i <= end; i++)
    {
        ppat->buf[0 * total_needle + i] = (i % 2) ? 4 : 5;
        ppat->buf[1 * total_needle + i] = (i % 2) ? 4 : 5;
    }
    /* 落布 */
    for (i = start; i < range.pat_start + sp - 1; i++)
    {
        ppat->buf[2 * total_needle + i] = 4;
        ppat->buf[3 * total_needle + i] = 4;
    }
    /* 行定 */
    printf ("loop range: start = %d, end = %d\n", range.pat_start + sp - 1, end);
    for (i = range.pat_start + sp - 1; i <= end; i++)
    {
        ppat->buf[4 * total_needle + i] = (i % 2) ? 4 : 5;
        ppat->buf[5 * total_needle + i] = (i % 2) ? 4 : 5;
    }

    /* cnt */
    pcnt = &p->pk_data.pcnt;

    pcnt->rows = (first_loop_times > 10) ? 10 : 12;
    pcnt->buf = (uchar*)calloc(pcnt->rows, sizeof(KNIT_PAGE));

    /* 1,2 慢速*/
    pk_setup_loop_data_cnt(p, pcnt->buf, 1, 2, 0);
    /* 3,4行定 */
    pk_setup_loop_data_cnt(p, pcnt->buf + 2 * sizeof(KNIT_PAGE), 3, 4, first_loop_times);
    /* 第5行，右行编织，纱嘴停在右边 */
    pbuf = pcnt->buf + 4 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)(pcnt->buf + 2 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 第6行，左行落布 */
    pbuf = pcnt->buf + 5 * sizeof(KNIT_PAGE);
    KNIT_PAGE *pcon_hd_end = GetControlPage(p, hd_end);
    memcpy((void*)pbuf, (void*)pcon_hd_end, sizeof(KNIT_PAGE));
    SET_SYS1_FPR(pbuf, 3);
    SET_SYS1_FC(pbuf, 8);
    SET_SYS1_BPR(pbuf, 3);
    SET_SYS1_BC(pbuf, 8);
    SET_SYS1_FAC(pbuf, 0x01 << 4);
    SET_SYS1_BAC(pbuf, 0x01 << 4);
    SET_SYS1_YC(pbuf, 0);

    SET_SYS2_FPR(pbuf, 4);
    SET_SYS2_FC(pbuf, 8);
    SET_SYS2_BPR(pbuf, 4);
    SET_SYS2_BC(pbuf, 8);
    SET_SYS2_FAC(pbuf, 0x01 << 4);
    SET_SYS2_BAC(pbuf, 0x01 << 4);
    SET_SYS2_YC(pbuf, 0);

    /* 第7行 */
    pbuf = pcnt->buf + 6 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 5 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 第8行 */
    pbuf = pcnt->buf + 7 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 5 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 第9行 */
    pbuf = pcnt->buf + 8 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 5 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 第10行,左行编织 */
    pbuf = pcnt->buf + 9 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)(pcnt->buf + 3 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    if (pcon_hd_end->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 5);
    }
    if (pcon_hd_end->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 5);
    }
    if (pcon_hd_end->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 6);
    }
    if (pcon_hd_end->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 6);
    }
    SET_LOOP_START(pbuf, 0);
    SET_LOOP_END(pbuf, 0);
    SET_LOOP_NUM(pbuf, 0);

    /* 11,12行 */
    if (pcnt->rows > 10)
    {
        pbuf = pcnt->buf + 10 * sizeof(KNIT_PAGE);
        memcpy((void*)pbuf, (void*)(pcnt->buf + 2 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
        if (pcon_hd_end->flw_1F != 0)
        {
            SET_SYS1_FPR(pbuf, 5);
        }
        if (pcon_hd_end->flw_1B != 0)
        {
            SET_SYS1_BPR(pbuf, 5);
        }
        if (pcon_hd_end->flw_2F != 0)
        {
            SET_SYS2_FPR(pbuf, 6);
        }
        if (pcon_hd_end->flw_2B != 0)
        {
            SET_SYS2_BPR(pbuf, 6);
        }

        pbuf = pcnt->buf + 11 * sizeof(KNIT_PAGE);
        memcpy((void*)pbuf, (void*)(pcnt->buf + 9 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));

        d = end - min_end;

        if (d <= 10)
        {
            loop_num = 3;
        }
        else if (d <= 15)
        {
            loop_num = 8;
        }
        else
        {
            loop_num = 15;
        }

        if (p->need_loop & LOOP_SY_BIT)
        {
            loop_num = 15;
        }

        SET_LOOP_START(pbuf, pcnt->rows - 1);
        SET_LOOP_END(pbuf, pcnt->rows);
        SET_LOOP_NUM(pbuf, loop_num);
    }
    return 0;
}
/*
 * 获取行定类型2数据，先落左边，再行定
 * @param row 从第row行开始编织,从１开始
 * @param[out] pcnt 控制缓冲区
 * @param[out] ppat 花样缓冲区
 * NOTE: 片子右移
 */
int pk_get_loop_data2_noloop(MH_KNIT *p, int row)
{
    int i = 0;
    int hd_start = 0;
    int hd_end = 0;
    uchar *pbuf;
    PAT_RANGE range = { 0 };
    int total_needle = p->total_needle;

    int min_end;
    int d;
    int loop_num;

    /* 行定起点 */
    int start = 0;
    /* 行定终点 */
    int end = 0;

    PK_DATA *pcnt;
    PK_DATA *ppat;

    p->pk_data.pcnt.rows = 0;
    FREE(p->pk_data.pcnt.buf);

    p->pk_data.ppat.rows = 0;
    FREE(p->pk_data.ppat.buf);

    hd_start = p->hangding_start;
    hd_end = hd_start + 1;

    if ((p->knit_page == NULL) || (p->total_line < hd_end))
    {
        return 1;
    }

    int sp = p->start_needle;
    sp -= p->left_bound;

    backpiece_get_pattern_range(p, row, &range);

    start = __min(range.pat_start + sp - 1, p->knit_start + p->sp - 1);
    end = __max(range.pat_end + sp - 1, p->knit_end + p->sp - 1);
    min_end = __min(range.pat_end + sp - 1, p->knit_end + p->sp - 1);

    if ((start < 0) || (end < 0) ||
        (start > total_needle) || (end > total_needle))
    {
        return 0;
    }
    /*
     * 1----> 落布
     * 2<---- 落布
     * 3----> 落布
     * 4<---  落布
     * 5----> 编织,慢速
     * 6<---  编织，慢速
     * 7----> 编织，快速
     * 8<---- 编织，快速
     */

    /* pat */
    p->pk_data.pat_width = total_needle;
    ppat = &p->pk_data.ppat;

    ppat->rows = 4;
    ppat->buf = (uchar*)calloc(total_needle * ppat->rows, sizeof (uchar));
    /* 落布 */
    for (i = start; i < range.pat_start + sp - 1; i++)
    {
        ppat->buf[0 * total_needle + i] = 4;
        ppat->buf[1 * total_needle + i] = 4;
    }
    /* 行定 */
    for (i = range.pat_start + sp - 1; i <= end; i++)
    {
        ppat->buf[2 * total_needle + i] = (i % 2) ? 4 : 5;
        ppat->buf[3 * total_needle + i] = (i % 2) ? 4 : 5;
    }

    /* cnt */
    pcnt = &p->pk_data.pcnt;

    pcnt->rows = 8;
    pcnt->buf = (uchar*)calloc(pcnt->rows, sizeof(KNIT_PAGE));

    /* 第1，2行 */
    pbuf = pcnt->buf;
    memcpy((void*)pbuf, (void*)GetControlPage(p, 1), sizeof(KNIT_PAGE));
    SET_SYS1_FPR(pbuf, 1);
    SET_SYS1_FC(pbuf, 8);
    SET_SYS1_BPR(pbuf, 1);
    SET_SYS1_BC(pbuf, 8);
    SET_SYS1_FAC(pbuf, 0x01 << 4);
    SET_SYS1_BAC(pbuf, 0x01 << 4);
    SET_SYS1_YC(pbuf, 0);

    SET_SYS2_FPR(pbuf, 2);
    SET_SYS2_FC(pbuf, 8);
    SET_SYS2_BPR(pbuf, 2);
    SET_SYS2_BC(pbuf, 8);
    SET_SYS2_FAC(pbuf, 0x01 << 4);
    SET_SYS2_BAC(pbuf, 0x01 << 4);
    SET_SYS2_YC(pbuf, 0);

    pbuf = pcnt->buf + 1 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)pcnt->buf, sizeof(KNIT_PAGE));
    /* 第3，4行 */
    KNIT_PAGE *pcon_hd_start = GetControlPage(p, hd_start);
    pbuf = pcnt->buf + 2 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)pcon_hd_start, sizeof(KNIT_PAGE));
    SET_SYS1_FPR(pbuf, 1);
    SET_SYS1_FC(pbuf, 8);
    SET_SYS1_BPR(pbuf, 1);
    SET_SYS1_BC(pbuf, 8);
    SET_SYS1_FAC(pbuf, 0x01 << 4);
    SET_SYS1_BAC(pbuf, 0x01 << 4);
    SET_SYS1_YC(pbuf, 0);

    SET_SYS2_FPR(pbuf, 2);
    SET_SYS2_FC(pbuf, 8);
    SET_SYS2_BPR(pbuf, 2);
    SET_SYS2_BC(pbuf, 8);
    SET_SYS2_FAC(pbuf, 0x01 << 4);
    SET_SYS2_BAC(pbuf, 0x01 << 4);
    SET_SYS2_YC(pbuf, 0);

    pbuf = pcnt->buf + 3 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 2 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 5行，慢速编织 */
    pbuf = pcnt->buf + 4 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)GetControlPage(p, 1), sizeof(KNIT_PAGE));
    if (pcon_hd_start->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 3);
    }
    if (pcon_hd_start->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 3);
    }
    if (pcon_hd_start->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 4);
    }
    if (pcon_hd_start->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 4);
    }

    /* 第6行，慢速编织 */
    pbuf = pcnt->buf + 5 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)GetControlPage(p, 2), sizeof(KNIT_PAGE));
    KNIT_PAGE *pcon_hd_end = GetControlPage(p, hd_end);
    if (pcon_hd_end->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 3);
    }
    if (pcon_hd_end->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 3);
    }
    if (pcon_hd_end->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 4);
    }
    if (pcon_hd_end->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 4);
    }

    SET_LOOP_START(pbuf, 0);
    SET_LOOP_END(pbuf, 0);
    SET_LOOP_NUM(pbuf, 0);

    /* 7行，快速编织 */
    pbuf = pcnt->buf + 6 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)pcon_hd_start, sizeof(KNIT_PAGE));
    if (pcon_hd_start->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 3);
    }
    if (pcon_hd_start->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 3);
    }
    if (pcon_hd_start->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 4);
    }
    if (pcon_hd_start->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 4);
    }

    /* 第8行，快速编织 */
    pbuf = pcnt->buf + 7 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)pcon_hd_end, sizeof(KNIT_PAGE));
    if (pcon_hd_end->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 3);
    }
    if (pcon_hd_end->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 3);
    }
    if (pcon_hd_end->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 4);
    }
    if (pcon_hd_end->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 4);
    }
    d = end - min_end;

    if (d <= 5)
    {
        loop_num = 2;
    }
    else if (d <= 10)
    {
        loop_num = 9;
    }
    else if (d <= 15)
    {
        loop_num = 17;
    }
    else
    {
        loop_num = 24;
    }

    if (p->need_loop & LOOP_SY_BIT)
    {
        loop_num = 25;
    }

    SET_LOOP_START(pbuf, pcnt->rows - 1);
    SET_LOOP_END(pbuf, pcnt->rows);
    SET_LOOP_NUM(pbuf, loop_num);

    return 0;
}
/*
 * 落两边
 */
int pk_get_auto_drop_data(MH_KNIT *p, int row)
{
    int i = 0;
    int width;
    PAT_RANGE range = { 0 };
    int start;
    int end;
    uchar *pbuf;
    int hd_start = 0;
    int hd_end = 0;
    int loop_times = 2;
    int total_needle = p->total_needle;
    int sp = p->start_needle;
    sp -= p->left_bound;

    PK_DATA *pcnt;
    PK_DATA *ppat;

    p->pk_data.pcnt.rows = 0;
    FREE(p->pk_data.pcnt.buf);

    p->pk_data.ppat.rows = 0;
    FREE(p->pk_data.ppat.buf);

    hd_start = p->hangding_start;
    hd_end = hd_start + 1;

    backpiece_get_pattern_range(p, row, &range);

    /* 比后片起始行窄就不需要落布了 */
    if ((p->knit_start + p->sp >= range.pat_start + sp) &&
        (p->knit_end + p->sp <= range.pat_end + sp))
    {
        p->sp = sp;
        return 0;
    }

    p->pk_data.pat_width = total_needle;
    width = total_needle;

    if ((p->need_loop & LOOP_SY_BIT) ||
        ((p->need_loop & LOOP_KC_BIT) == KNITING))
    {
        loop_times = 24;
    }

    /*
     * 1----> 编织
     * 2<---- 编织    1,2慢速
     * 3----> 编织
     * 4<---- 编织    3,4循环
     * 5----> 编织　　 纱嘴停到右边
     * 6<---- 落布    落左边
     * 7----> 落布
     * 8<---- 落布
     * 9----> 落布
     * 10<---- 编织    纱嘴停到左边
     * 11----> 落布    落右边
     * 12<--- 落布
     * 13---> 落布
     * 14<--- 落布
     */

    start = __min(range.pat_start + sp - 1, p->knit_start + p->sp - 1);
    end = __max(range.pat_end + sp - 1, p->knit_end + p->sp - 1);

    if ((start < 0) || (end < 0) ||
        (start > width) || (end > width))
    {
        return 0;
    }

    /* pat */
    ppat = &p->pk_data.ppat;
    ppat->rows = 6;
    ppat->buf = (uchar*)calloc(width * ppat->rows, sizeof (uchar));


    /* 1,2行,行定 */
    for (i = start; i <= end; i++)
    {
        ppat->buf[0 * width + i] = (i % 2) ? 4 : 5;
        ppat->buf[1 * width + i] = (i % 2) ? 4 : 5;
    }

    /* 第3行，落左边 */
    int w = 0;
    for (w = p->knit_start + p->sp - 1; w < range.pat_start + sp - 1; w++)
    {
        ppat->buf[2 * width + w] = 4;
    }

    /* 第4,5行，纱嘴带到左边 */
    for (i = range.pat_start + sp - 1; i <= end; i++)
    {
        ppat->buf[3 * width + i] = (i % 2) ? 4 : 5;
        ppat->buf[4 * width + i] = (i % 2) ? 4 : 5;
    }

    /* 第6行，落右边 */
    for (w = range.pat_end + sp; w <= p->knit_end + p->sp - 1; w++)
    {
        ppat->buf[5 * width + w] = 4;
    }

    /* cnt */
    pcnt = &p->pk_data.pcnt;
    pcnt->rows = 14;
    pcnt->buf = (uchar*)calloc(pcnt->rows, sizeof(KNIT_PAGE));

    /* 1,2慢速 */
    pk_setup_loop_data_cnt(p, pcnt->buf, 1, 2, 0);
    /* 3,4行定 */
    pk_setup_loop_data_cnt(p, pcnt->buf + 2 * sizeof(KNIT_PAGE), 3, 4, loop_times);

    /* 第5行，右行编织，纱嘴停在右边 */
    pbuf = pcnt->buf + 4 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)(pcnt->buf + 2 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 第6行，左行落布 */
    pbuf = pcnt->buf + 5 * sizeof(KNIT_PAGE);
    KNIT_PAGE *pcon_hd_end = GetControlPage(p, hd_end);
    memcpy((void*)pbuf, (void*)pcon_hd_end, sizeof(KNIT_PAGE));
    SET_SYS1_FPR(pbuf, 3);
    SET_SYS1_FC(pbuf, 8);
    SET_SYS1_BPR(pbuf, 3);
    SET_SYS1_BC(pbuf, 8);
    SET_SYS1_FAC(pbuf, 0x01 << 4);
    SET_SYS1_BAC(pbuf, 0x01 << 4);
    SET_SYS1_YC(pbuf, 0);

    SET_SYS2_FPR(pbuf, 3);
    SET_SYS2_FC(pbuf, 8);
    SET_SYS2_BPR(pbuf, 3);
    SET_SYS2_BC(pbuf, 8);
    SET_SYS2_FAC(pbuf, 0x01 << 4);
    SET_SYS2_BAC(pbuf, 0x01 << 4);
    SET_SYS2_YC(pbuf, 0);

    /* 第7行 */
    pbuf = pcnt->buf + 6 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 5 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 第8行 */
    pbuf = pcnt->buf + 7 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 5 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 第9行 */
    pbuf = pcnt->buf + 8 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 5 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 第10行,左行编织 */
    pbuf = pcnt->buf + 9 * sizeof(KNIT_PAGE);
    memcpy ((void*)pbuf, (void*)(pcnt->buf + 3 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    if (pcon_hd_end->flw_1F != 0)
    {
        SET_SYS1_FPR(pbuf, 4);
    }
    if (pcon_hd_end->flw_1B != 0)
    {
        SET_SYS1_BPR(pbuf, 4);
    }
    if (pcon_hd_end->flw_2F != 0)
    {
        SET_SYS2_FPR(pbuf, 5);
    }
    if (pcon_hd_end->flw_2B != 0)
    {
        SET_SYS2_BPR(pbuf, 5);
    }
    SET_LOOP_START(pbuf, 0);
    SET_LOOP_END(pbuf, 0);
    SET_LOOP_NUM(pbuf, 0);

    /* 11-14,落右边 */
    pbuf = pcnt->buf + 10 * sizeof(KNIT_PAGE);
    KNIT_PAGE *pcon_hd_start = GetControlPage(p, hd_start);
    memcpy((void*)pbuf, (void*)pcon_hd_start, sizeof(KNIT_PAGE));
    SET_SYS1_FPR(pbuf, 6);
    SET_SYS1_FC(pbuf, 8);
    SET_SYS1_BPR(pbuf, 6);
    SET_SYS1_BC(pbuf, 8);
    SET_SYS1_FAC(pbuf, 0x01 << 4);
    SET_SYS1_BAC(pbuf, 0x01 << 4);
    SET_SYS1_YC(pbuf, 0);

    SET_SYS2_FPR(pbuf, 6);
    SET_SYS2_FC(pbuf, 8);
    SET_SYS2_BPR(pbuf, 6);
    SET_SYS2_BC(pbuf, 8);
    SET_SYS2_FAC(pbuf, 0x01 << 4);
    SET_SYS2_BAC(pbuf, 0x01 << 4);
    SET_SYS2_YC(pbuf, 0);

    /* 第12行 */
    pbuf = pcnt->buf + 11 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 10 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 第13行 */
    pbuf = pcnt->buf + 12 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 10 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    /* 第14行 */
    pbuf = pcnt->buf + 13 * sizeof(KNIT_PAGE);
    memcpy((void*)pbuf, (void*)(pcnt->buf + 10 * sizeof(KNIT_PAGE)), sizeof(KNIT_PAGE));
    return 0;
}
/*
 * 用于后片循环，当针板上的片子宽度与指定行宽度不一样时，把超出部分落掉
 */
int pk_get_auto_drop_data_noloop(MH_KNIT *p, int row)
{
    int i = 0;
    int n = 0;
    int width;
    PAT_RANGE range = { 0 };
    int start;
    int end;
    int hd_start;
    int hd_end;
    int total_needle = p->total_needle;
    int sp = p->start_needle;
    sp -= p->left_bound;

    hd_start = p->hangding_start;
    hd_end = hd_start + 1;

    PK_DATA *pcnt;
    PK_DATA *ppat;

    p->pk_data.pcnt.rows = 0;
    FREE(p->pk_data.pcnt.buf);

    p->pk_data.ppat.rows = 0;
    FREE(p->pk_data.ppat.buf);

    backpiece_get_pattern_range(p, row, &range);

    /* 比后片起始行窄就不需要落布了 */
    if ((p->knit_start + p->sp >= range.pat_start + sp) &&
        (p->knit_end + p->sp <= range.pat_end + sp))
    {
        p->sp = sp;
        return 0;
    }

    p->pk_data.pat_width = total_needle;
    width = total_needle;

    start = __min(range.pat_start + sp - 1, p->knit_start + p->sp - 1);
    end = __max(range.pat_end + sp - 1, p->knit_end + p->sp - 1);

    if ((start < 0) || (end < 0) ||
        (start > total_needle) || (end > total_needle))
    {
        return 0;
    }

    /* pat */
    ppat = &p->pk_data.ppat;
    ppat->rows = 4;
    ppat->buf = (uchar*)calloc(total_needle * ppat->rows, sizeof (uchar));

    int w = 0;
    /* 左侧 */
    for (w = p->knit_start + p->sp - 1; w < range.pat_start + sp - 1; w++)
    {
        /* row 1 */
        ppat->buf[0 * width + w] = 1;
        /* row 2 */
        ppat->buf[1 * width + w] = 1;
        /* row 3 */
        ppat->buf[2 * width + w] = 1;
        /* row 4 */
        ppat->buf[3 * width + w] = 1;
    }

    /* 右侧 */
    for (w = range.pat_end + sp; w <= p->knit_end + p->sp - 1; w++)
    {
        /* row 1 */
        ppat->buf[0 * width + w] = 1;
        /* row 2 */
        ppat->buf[1 * width + w] = 1;
        /* row 3 */
        ppat->buf[2 * width + w] = 1;
        /* row 4 */
        ppat->buf[3 * width + w] = 1;
    }

    /* cnt */
    pcnt = &p->pk_data.pcnt;
    pcnt->rows = 4;
    pcnt->buf = (uchar*)calloc(pcnt->rows, sizeof(KNIT_PAGE));

    /* 1-4 */
    for (n = 0; n < pcnt->rows; n++)
    {
        uchar *pbuf = pcnt->buf + n * sizeof(KNIT_PAGE);
        if (n < 2)
        {
            memcpy((void*)pbuf, (void*)GetControlPage(p, 1), sizeof(KNIT_PAGE));
        }
        else
        {
            memcpy((void*)pbuf, (void*)GetControlPage(p, hd_start), sizeof(KNIT_PAGE));
        }
        /* 系统１前床，后床；系统２前床，后床 */
        for (i = 0; i < 4; i++)
        {
            /* 花样行 */
            pbuf[0 + 10 * i] = 1 + n;
            /* 编织动作 */
            pbuf[2 + 10 * i] = 0x08;
            /* 色码,1号色 */
            pbuf[3 + 10 * i] = 0x02;
        }
        SET_SYS1_YC(pbuf, 0);
        SET_SYS2_YC(pbuf, 0);
    }
    return 0;
}
/*
 * 获取自动起底部分的数据
 */
int pk_get_auto_comb_data(MH_KNIT *p)
{
    PK_DATA *ppat;
    PK_DATA *pcnt;

    p->pk_data.pcnt.rows = 0;
    FREE(p->pk_data.pcnt.buf);

    p->pk_data.ppat.rows = 0;
    FREE(p->pk_data.ppat.buf);

    int mode = p->board_param.start_knit_mode;
    if(mode < 1 || mode > 3)
    {
        mode = 1;
    }
    int pwidth = p->flower_width;
    int width = p->total_needle;

    p->pk_data.pat_width = width;
    p->pk_data.ppat.rows = 2;
    p->pk_data.ppat.buf = calloc(2, width);

    p->pk_data.pcnt.rows = 2;
    p->pk_data.pcnt.buf = calloc(2, sizeof(KNIT_PAGE));

    ppat = &p->pk_data.ppat;
    pcnt = &p->pk_data.pcnt;

    //search for start
    int start = 0;
    int w = 0;
    int org_start;
    int sp = p->start_needle;    //start pos
    sp -= p->left_bound;

    for(w = 0; w < pwidth; ++w)
    {
        if(p->flower_data[w] && p->flower_data[w] != 0x0F)
        {
            start = w;
            break;
        }
    }
    org_start = start;
    if (mode == 3)
    {
        start = ((sp + start - 1) / 3) * 3 + 1 - sp;
    }
    else if (mode == 2)
    {
        start = ((sp + start) % 2) ? (start - 1) : start;
    }
    //search for end
    int end = 0;
    for(w = pwidth - 1; w >= 0; --w)
    {
        if(p->flower_data[w] && p->flower_data[w] != 0x0F)
        {
            end = w + 1;
            break;
        }
    }
    //line 1
    for(w = start; w < end; w++)
    {
        if(w < org_start)
        {
            continue;
        }
        else if(mode == 1)//1x1
        {
            ppat->buf[w + sp - 1] = (w - start) & 1 ? 9 : 8;
        }
        else if(mode == 2)//2x2
        {
            ppat->buf[w + sp - 1] = (w - start) & 2 ? 9 : 8;
        }
        else if(mode == 3)//3x3
        {
            ppat->buf[w + sp - 1] = ((w - start) % 6) < 3 ? 8 : 9;
        }
    }
    //line2
    for(w = start; w < end; w++)
    {
        if (w < org_start)
        {
            continue;
        }
        else if(mode == 1)//1x1
        {
            ppat->buf[width + w + sp - 1] = (w - start) & 1 ? 8 : 9;
        }
        else if(mode == 2)//2x2
        {
            ppat->buf[width + w + sp - 1] = (w - start) & 2 ? 8 : 9;
        }
        else if(mode == 3)//3x3
        {
            ppat->buf[width + w + sp - 1] = ((w - start) % 6) < 3 ? 9 : 8;
        }
    }
    //control
    uchar yarn = p->board_param.gauze;
    int wyarn = 0x8000 >> (yarn - 1);
    if(p->sys_info.cam > 1)
    {
        pcnt->buf[20] = 1;
        pcnt->buf[22] = 0x08;
        pcnt->buf[24] = 0x01;
        pcnt->buf[26] = 0x08;
        pcnt->buf[30] = 1;
        pcnt->buf[32] = 0x08;
        pcnt->buf[34] = 0x02;
        pcnt->buf[36] = 0x08;
        pcnt->buf[83] = wyarn & 0x00FF;
        pcnt->buf[84] = (wyarn & 0xFF00) >> 8;
        pcnt->buf[85] = 0x81;
        pcnt->buf[102] = 27;
        pcnt->buf[128 + 20] = 2;
        pcnt->buf[128 + 22] = 0x08;
        pcnt->buf[128 + 24] = 0x01;
        pcnt->buf[128 + 26] = 0x08;
        pcnt->buf[128 + 30] = 2;
        pcnt->buf[128 + 32] = 0x08;
        pcnt->buf[128 + 34] = 0x02;
        pcnt->buf[128 + 36] = 0x08;
        pcnt->buf[128 + 83] = wyarn & 0x00FF;
        pcnt->buf[128 + 84] = (wyarn & 0xFF00) >> 8;
        pcnt->buf[128 + 85] = 0x82;
        pcnt->buf[128 + 102] = 27;
    }
    else
    {
        pcnt->buf[0] = 1;
        pcnt->buf[2] = 0x08;
        pcnt->buf[4] = 0x01;
        pcnt->buf[6] = 0x08;
        pcnt->buf[10] = 1;
        pcnt->buf[12] = 0x08;
        pcnt->buf[14] = 0x02;
        pcnt->buf[16] = 0x08;
        pcnt->buf[80] = wyarn & 0x00FF;
        pcnt->buf[81] = (wyarn & 0xFF00) >> 8;
        pcnt->buf[82] = 0x81;
        pcnt->buf[92] = 27;
        pcnt->buf[128 + 0] = 2;
        pcnt->buf[128 + 2] = 0x08;
        pcnt->buf[128 + 4] = 0x01;
        pcnt->buf[128 + 6] = 0x08;
        pcnt->buf[128 + 10] = 2;
        pcnt->buf[128 + 12] = 0x08;
        pcnt->buf[128 + 14] = 0x02;
        pcnt->buf[128 + 16] = 0x08;
        pcnt->buf[128 + 80] = wyarn & 0x00FF;
        pcnt->buf[128 + 81] = (wyarn & 0xFF00) >> 8;
        pcnt->buf[128 + 82] = 0x82;
        pcnt->buf[128 + 92] = 27;
    }
    pcnt->buf[128 + 111] = 1;
    int i = 0;
    for(i = 0; i < 2; i++)
    {
        pcnt->buf[(i << 7) + 93] = 27;
        pcnt->buf[(i << 7) + 94] = 27;
        pcnt->buf[(i << 7) + 95] = 27;
        pcnt->buf[(i << 7) + 96] = 27;
        pcnt->buf[(i << 7) + 97] = 1;
        pcnt->buf[(i << 7) + 107] = 1;
        pcnt->buf[(i << 7) + 108] = 1;
        pcnt->buf[(i << 7) + 112] = 1;
        pcnt->buf[(i << 7) + 119] = 1;
        pcnt->buf[(i << 7) + 120] = 1;
    }
    return 0;
}
/*
 * @note: 获取卸片数据
 */
int pk_get_unload_data(MH_KNIT *p)
{
    int total_needle = p->total_needle;
    int w = p->knit_start;
    int i = 0;

    PK_DATA *ppat;
    PK_DATA *pcnt;

    p->pk_data.pcnt.rows = 0;
    FREE(p->pk_data.pcnt.buf);

    p->pk_data.ppat.rows = 0;
    FREE(p->pk_data.ppat.buf);

    p->pk_data.pat_width = p->flower_width;
    p->pk_data.ppat.rows = 1;
    p->pk_data.ppat.buf = (uchar*)calloc(p->pk_data.ppat.rows, p->pk_data.pat_width);

    p->pk_data.pcnt.rows = 2;
    p->pk_data.pcnt.buf = (uchar*)calloc(p->pk_data.pcnt.rows, sizeof(KNIT_PAGE));

    ppat = &p->pk_data.ppat;
    pcnt = &p->pk_data.pcnt;

    printf("prefixknit start :%d  end:%d\n",p->knit_start, p->knit_end);
    if ((p->knit_start < 0) || (p->knit_start >= total_needle) ||
        (p->knit_end < 0) || (p->knit_end >= total_needle))
    {
        return -1;
    }
    if(p->knit_end > p->flower_width)
    {
        p->knit_end =p->flower_width - p->knit_start;
    }
    /* pat */
    for (; w < p->knit_end; w++)
    {
        ppat->buf[w] = w & 1 ? 9 : 8;
    }


    /* cnt */
    p->pk_data.pcnt.buf[0] = 1;
    p->pk_data.pcnt.buf[2] = 0x08;
    p->pk_data.pcnt.buf[4] = 0x03;//0x01;
    p->pk_data.pcnt.buf[6] = 0x08;
    p->pk_data.pcnt.buf[20] = 1;
    p->pk_data.pcnt.buf[22] = 0x08;
    p->pk_data.pcnt.buf[24] = 0x03;//0x01;
    p->pk_data.pcnt.buf[26] = 0x08;

    if(p->sys_info.cam == 1)
    {
        p->pk_data.pcnt.buf[128 + 10] = 1;
        p->pk_data.pcnt.buf[128 + 12] = 0x08;
        p->pk_data.pcnt.buf[128 + 14] = 0x03;//0x01;
        p->pk_data.pcnt.buf[128 + 16] = 0x08;
    }
    else
    {
        p->pk_data.pcnt.buf[128 + 10] = 1;
        p->pk_data.pcnt.buf[128 + 12] = 0x08;
        p->pk_data.pcnt.buf[128 + 14] = 0x03;//0x01;
        p->pk_data.pcnt.buf[128 + 16] = 0x08;

        p->pk_data.pcnt.buf[128 + 30] = 1;
        p->pk_data.pcnt.buf[128 + 32] = 0x08;
        p->pk_data.pcnt.buf[128 + 34] = 0x03;//0x01;
        p->pk_data.pcnt.buf[128 + 36] = 0x08;
    }

    for(i = 0; i < 2; i++)
    {
        p->pk_data.pcnt.buf[(i << 7) + 93] = 1;
        p->pk_data.pcnt.buf[(i << 7) + 94] = 1;
        p->pk_data.pcnt.buf[(i << 7) + 95] = 1;
        p->pk_data.pcnt.buf[(i << 7) + 96] = 1;
        p->pk_data.pcnt.buf[(i << 7) + 97] = 1;
        p->pk_data.pcnt.buf[(i << 7) + 107] = 1;
        p->pk_data.pcnt.buf[(i << 7) + 108] = 1;
        p->pk_data.pcnt.buf[(i << 7) + 112] = 1;
        p->pk_data.pcnt.buf[(i << 7) + 119] = 1;
        p->pk_data.pcnt.buf[(i << 7) + 120] = 1;
    }

    return 0;
}
/*
 * 获取行定数据,当前片子比针板上片子宽时，只打行定，不落布
 * @param row: 从第row行开始编织,从１开始
 */
int pk_get_cycle_data(MH_KNIT *p, int row)
{
    int i = 0;
    int hd_start = 0;
    int hd_end = 0;
    PAT_RANGE range = { 0 };
    int loop_times = 3;

    PK_DATA *pcnt;
    PK_DATA *ppat;

    int total_needle = p->total_needle;

    /* 行定起点 */
    int start = 0;
    /* 行定终点 */
    int end = 0;

    p->pk_data.pcnt.rows = 0;
    FREE(p->pk_data.pcnt.buf);

    p->pk_data.ppat.rows = 0;
    FREE(p->pk_data.ppat.buf);

    hd_start = p->hangding_start;
    hd_end = hd_start + 1;

    if ((p->knit_page == NULL) || (p->total_line < hd_end))
    {
        return 1;
    }

    int sp = p->start_needle;
    sp -= p->left_bound;

    printf("sp = %d\n", sp);

    backpiece_get_pattern_range(p, row, &range);

    start = range.pat_start + sp - 1;
    end = range.pat_end + sp - 1;

    if ((start < 0) || (end < 0) ||
        (start > total_needle) || (end > total_needle))
    {
        return 0;
    }

    int dl = p->knit_start + p->sp -1 - start;
    int dr = p->knit_end + p->sp -1 - end;
    int d = __max(abs(dl), abs(dr));

    if (d > 0)
    {
        if (d <= 5)
        {
            loop_times = 3;
        }
        else if (d <= 10)
        {
            loop_times = 10;
        }
        else if (d <= 15)
        {
            loop_times = 18;
        }
        else
        {
            loop_times = 25;
        }
    }
    /*
     * 1----> 编织
     * 2<---- 编织    1,2慢速
     * 3----> 编织
     * 4<---- 编织    3,4循环10次
     */

    p->pk_data.pat_width = total_needle;

    ppat = &p->pk_data.ppat;

    /* pat */
    ppat->rows = 2;
    ppat->buf = (uchar*)calloc(p->pk_data.pat_width * ppat->rows, sizeof (uchar));
    /* 行定 */
    for (i = start; i <= end; i++)
    {
        ppat->buf[0 * total_needle + i] = (i % 2) ? 4 : 5;
        ppat->buf[1 * total_needle + i] = (i % 2) ? 4 : 5;
    }

    /* cnt */
    pcnt = &p->pk_data.pcnt;

    if ((p->need_loop & LOOP_SY_BIT) ||
        ((p->need_loop & LOOP_KC_BIT) == KNITING))
    {
        loop_times = 25;
    }

    printf ("start = %d, end = %d, loop_times = %d\n", start, end, loop_times);

    pcnt->rows = 4;
    pcnt->buf = (uchar*)calloc(pcnt->rows, sizeof(KNIT_PAGE));

    /* 1, 2行 */
    pk_setup_loop_data_cnt(p, pcnt->buf, 1, 2, 0);
    /* 3, 4行定 */
    pk_setup_loop_data_cnt(p, pcnt->buf + 2 * sizeof(KNIT_PAGE), 3, 4, loop_times - 1);

    return 0;
}
/*
 *
 */
void pk_clear_data(MH_KNIT *p)
{
    p->pk_data.pcnt.rows = 0;
    FREE(p->pk_data.pcnt.buf);

    p->pk_data.ppat.rows = 0;
    FREE(p->pk_data.ppat.buf);
}
/*
 * @param row: 从第row行开始编织,从１开始
 * @param type: ０，获取自动起底板数据；2,卸片；其他，自动行定落布
 * @param manual_loop: 是否手动打行定
 */
int pk_init_data(MH_KNIT *p, int row, int type, int manual_loop)
{
    int total_needle = p->total_needle;
    /* clear */
    pk_clear_data(p);

    if ((p->knit_start < 0) || (p->knit_start >= total_needle) ||
        (p->knit_end < 0) || (p->knit_end >= total_needle))
    {
        return 0;
    }

    if (type == PK_AUTO_BOARD)
    {
        /* 获取自动起底板数据 */
        if (p->board_enable)
        {
            p->pk_data.type = type;
            return pk_get_auto_comb_data(p);
        }
    }
    else if (type == PK_AUTO_DROP)
    {
        /* 卸片 */
        p->pk_data.type = type;
        return pk_get_unload_data(p);
    }
    else if (manual_loop)
    {
        p->pk_data.type = PK_AUTO_HD_DROP;
        return 0;
        return pk_get_auto_drop_data_noloop(p, row);
    }
    else
    {
        /* 获取自动行定落布数据 */
        int loop_type = 0;

        printf ("pk_init_data: row = %d\n", row);
        /* 是否需要打行定 */
        loop_type = pk_need_loop(p, row);

        printf ("pk_init_data: loop_type = %d, need_loop = %x\n", loop_type, p->need_loop);

        switch (loop_type)
        {
        case 0:
            /* 不需要落布 */
            p->pk_data.type = PK_AUTO_HD_DROP;
            return pk_get_cycle_data(p, row);
            break;
        case 3:
            p->pk_data.type = PK_AUTO_HD_DROP;
            return pk_get_auto_drop_data(p, row);
        case 1:
            /* 起针点左移，落右边 */
            p->pk_data.type = PK_AUTO_HD_DROP;
            return pk_get_loop_data1(p, row);
        case 2:
            /* 起针点右移，落左边 */
            p->pk_data.type = PK_AUTO_HD_DROP;
            return pk_get_loop_data2(p, row);
        default:
            break;
        }
    }

    return 0;
}
/*
 *
 */
short pk_get_loop_end(MH_KNIT *p, int row)
{
    uchar *buf;
    short end = 0;
    int i = 0;
    int des_row = row;

    if (p->pk_data.pcnt.buf == NULL)
    {
        return 0;
    }
    if (row < 0)
    {
        row = PK_ROUND(row);
    }

    if ((row >= 0) && (row < p->pk_data.pcnt.rows))
    {
        for (i = row; i < p->pk_data.pcnt.rows; i++)
        {
            buf = p->pk_data.pcnt.buf + i * sizeof(KNIT_PAGE);
            KNIT_PAGE *pcon = (KNIT_PAGE*)buf;
            if (pcon->economy_start == des_row)
            {
                end = pcon->economy_end;
                break;
            }
        }
    }

    return end;
}
/*
 *
 */
short pk_get_loop_num(MH_KNIT *p, int row)
{
    uchar *buf;
    short num = 0;
    int i = 0;
    int des_row = row;

    if (p->pk_data.pcnt.buf == NULL)
    {
        return 0;
    }
    if (row < 0)
    {
        row = PK_ROUND(row);
    }

    if ((row >= 0) && (row < p->pk_data.pcnt.rows))
    {
        for (i = row; i < p->pk_data.pcnt.rows; i++)
        {
            buf = p->pk_data.pcnt.buf + i * sizeof(KNIT_PAGE);
            KNIT_PAGE *pcon = (KNIT_PAGE*)buf;

            if (pcon->economy_start == des_row)
            {
                num = pcon->economy_num;
                break;
            }
        }
    }

    return num;
}
/*
 *
 */
int pk_get_cnt_buf(MH_KNIT *p, KNIT_PAGE *buf_out, int row)
{
    int ret = -1;
    if(row > 0 && row <= p->pk_data.pcnt.rows)
    {
        //printf("row: %d-%d\n", p->pk_data.pcnt.rows, row);
        uchar *buf;
        buf = p->pk_data.pcnt.buf + (row - 1) * sizeof(KNIT_PAGE);
        memcpy((void*) buf_out, (void*) buf, sizeof(KNIT_PAGE));
        ret = 0;
    }
    return ret;
}
/*
 *
 */
int IsPrefixKnit(MH_KNIT *p)
{
    return p->knit_state.prefix;
}
/*
 *
 */
void SetPrefixKnit(MH_KNIT *p, int n)
{
    p->knit_state.prefix = n;
}
/*
 *
 */
int GetPrefixPages(MH_KNIT *p)
{
    return p->pk_data.pcnt.rows;
}
/*
 *
 */
void pk_convert_economy(MH_KNIT *p)
{
    int i = 0;
    KNIT_PAGE *ptmp = calloc(1000, sizeof(KNIT_PAGE));
    int count = 0;
    ushort rows = p->pk_data.pcnt.rows;
    KNIT_PAGE *psrc = (KNIT_PAGE*)p->pk_data.pcnt.buf;
    for(i = 0; i < rows; ++i)
    {
        memcpy(ptmp + count, psrc + i, sizeof(KNIT_PAGE));
        ++count;
        ushort s = psrc[i].economy_start;
        ushort e = psrc[i].economy_end;
        ushort t = psrc[i].economy_num;
        if(s && e && t)
        {
            int j = 0;
            for(j = 0; j < t; ++j)
            {
                memcpy(ptmp + count, psrc + s - 1, sizeof(KNIT_PAGE) * (e - s + 1));
                count += e - s + 1;
            }
        }
    }
    if(count > rows)
    {
        free(p->pk_data.pcnt.buf);
        p->pk_data.pcnt.buf = calloc(count, sizeof(KNIT_PAGE));
        psrc = (KNIT_PAGE*)p->pk_data.pcnt.buf;
        memcpy(psrc, ptmp, sizeof(KNIT_PAGE) * count);
        p->pk_data.pcnt.rows = count;
    }
    free(ptmp);
}






